import json
import datetime
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from users.models import User
from django.views import View
from django.http import JsonResponse
import logging
from .models import Area, HouseImage, Facility
from homes.models import House
from django.core.cache import cache
from aijiazufang.utils.view import LoginRequiredMixin
from aijiazufang.utils.qiniuyun.qiniu_storage import img_url, storage

# 日志输出器
logger = logging.getLogger('django')


class DetailsPageView(View):

    def get(self, request, house_id):
        '''房屋详情页'''
        user = request.user
        # 判断是否登录.
        # 登录用户的用户id，如果没有登录，则为 -1
        if user:
            user_id = user.id
        else:
            user_id = -1

        # 判断house_id是否存在
        try:
            house = House.objects.get(id=house_id)

        except Exception as e:
            logger.error(e)
            return JsonResponse({
                "errno": 4001,
                "errmsg": "数据库查询错误",
            })

        # 拼接七牛云网址生成用户图形
        house_user = House.objects.get(id=house_id).user
        url = house_user.avatar
        user_avatar = str(url)

        # 构造返回数据
        data = {
            "house": {},
            "user_id": user_id
        }

        # 多对多查查询设施数据
        facilitie_list = []

        try:
            facilities = house.facility.all()
            for facilitie in facilities:
                facilitie_list.append(facilitie.id)

        except Exception as e:
            logger.error(e)
            return JsonResponse({
                "errno": 4001,
                "errmsg": "数据库查询错误",
            })

        # 一对多查询房屋图片
        image_list = []

        try:
            images = house.houseimage_set.all()
            for image in images:
                image_list.append(image.url)
            # 添加房源默认图片
            image_list.append(house.index_image_url)

        except Exception as e:
            logger.error(e)
            return JsonResponse({
                "errno": 4001,
                "errmsg": "数据库查询错误",
            })

        # 查询评论信息
        comment_list = []

        try:
            orders = house.order_set.all()
            for order in orders:
                comment_list.append({
                    "comment": order.comment,
                    "ctime": order.create_time,
                    "user_name": order.user.username
                })

        except Exception as e:
            logger.error(e)
            return JsonResponse({
                "errno": 4001,
                "errmsg": "数据库查询错误",
            })

        # 拼接数据
        data['house'] = {
            "acreage": house.acreage,
            "address": house.address,
            "beds": house.beds,
            "capacity": house.capacity,
            "comments": comment_list,
            "deposit": house.deposit,
            "facilities": facilitie_list,
            "hid": house.id,
            "img_urls": image_list,
            "max_days": house.max_days,
            "min_days": house.min_days,
            "price": house.price,
            "room_count": house.room_count,
            "title": house.title,
            "unit": house.unit,
            "user_avatar": user_avatar,
            "user_id": house.user.id,
            "user_name": house.user.username

        }

        # 返回数据
        return JsonResponse({
            "data": data,
            "errmsg": "OK",
            "errno": 0
        })


class HomeHouseView(View):
    # 新增房源

    def post(self, request):
        # 实现房源发布
        # 接受参数
        json_dict = json.loads(request.body.decode())
        title = json_dict.get('title')
        price = json_dict.get('price')
        area_id = json_dict.get('area_id')
        address = json_dict.get('address')
        room_count = json_dict.get('room_count')
        acreage = json_dict.get('acreage')
        unit = json_dict.get('unit')
        capacity = json_dict.get('capacity')
        beds = json_dict.get('beds')
        deposit = json_dict.get('deposit')
        min_days = json_dict.get('min_days')
        max_days = json_dict.get('max_days')
        facility = json_dict.get('facility')

        # 校验整体参数
        if not all(
                [title, price, area_id, address, room_count, acreage, unit, capacity, beds, deposit, min_days, max_days,
                 facility]):
            return JsonResponse({"errno": "4004",
                                 "errmsg": "缺少数据", })

        # 保存地址信息
        try:
            house = House.objects.create(
                user=request.user,
                title=title,
                price=price,
                area_id=area_id,
                address=address,
                room_count=room_count,
                acreage=acreage,
                unit=unit,
                capacity=capacity,
                beds=beds,
                deposit=deposit,
                min_days=min_days,
                max_days=max_days
            )
            # 添加设施数据
            house.facility.add(*facility)

        except Exception as e:
            return JsonResponse({'code': 4302,
                                 'errmsg': '文件读写错误'})

        data = {'house_id': house.id}

        # 返回数据
        return JsonResponse({"errno": "0",
                             "errmsg": "成功",
                             "data": data
                             })

    def get(self, request):
        """房屋搜索接口的实现"""

        # 1.接收参数
        aid = request.GET.get('aid')
        start_day = request.GET.get('sd')
        end_day = request.GET.get('ed')
        sk = request.GET.get('sk')
        page = request.GET.get('p')

        # 2.计算出 入住天数
        day_start = datetime.datetime.strptime(start_day, '%Y-%m-%d')
        day_end = datetime.datetime.strptime(end_day, '%Y-%m-%d')
        interval = day_end - day_start
        days = interval.days

        # 3.总体检验
        if not all([aid, start_day, end_day, sk, page]):
            return JsonResponse({'code': 4103,
                                 'errmsg': '传入参数有误'})

        # 4.单个检验
        if start_day >= end_day:
            return JsonResponse({'code': 4103,
                                 'errmsg': '传入的日期有误'})

        # 5.分页
        if page != 0:
            page = page

        else:
            page = 1

        try:
            # 6.根据传如的地区id获取该地区下所有房屋
            if "price-inc" == sk:
                all_houses = House.objects.filter(area_id=aid).filter(min_days__lte=days).order_by('price')

            elif "price-des" == sk:
                all_houses = House.objects.filter(area_id=aid).filter(min_days__lte=days).order_by('-price')

            elif "booking" == sk:
                all_houses = House.objects.filter(area_id=aid).filter(min_days__lte=days).order_by('-order_count')

            elif "new" == sk:
                all_houses = House.objects.filter(area_id=aid).filter(min_days__lte=days).order_by('create_time')

            else:
                return JsonResponse({'code': 4001,
                                     'errmsg': '查询数据出错'})


        except Exception as e:
            return JsonResponse({'code': 4001,
                                 'errmsg': '查询数据出错'})

        # 7.再根据传入的页码数，分页
        list = all_houses
        # 每页显示的条数
        paginator = Paginator(list, 2)

        try:
            page_house = paginator.page(page)

        except PageNotAnInteger:
            # 如果页面不是整数，则交付第一页。
            contacts = paginator.page(1)

        except EmptyPage:
            # 如果页面不是整数，请先交付页码。如果页面超出范围（例如9999），请交付结果的最后一页。
            contacts = paginator.page(paginator.num_pages)

        houses = []
        # 8.再获取每一个房屋信息，遍历
        for house in all_houses:
            # 9.再将所有的房屋信息放到一个字典中
            houses.append({
                'address': house.address,
                'area_name': house.area.name,
                'ctime': house.create_time,
                'house_id': house.id,
                'img_url': house.index_image_url,
                'order_count': house.order_count,
                'price': house.price,
                'room_count': house.room_count,
                'title': house.title,
                'user_avatar': str(house.user.avatar)
            })

        # 10.整理返回json数据
        return JsonResponse({
            "data": {
                "houses": houses,
                "total_page": page
            },
            "errmsg": "请求成功",

            "errno": "0"
        })


class MyhomelistView(LoginRequiredMixin, View):
    """我的房屋列表展示"""

    def get(self, request):
        # 获得当前用户

        user = request.user
        # 创建列表保存数据
        houses = []
        address = 'http://qcz5dw5aq.bkt.clouddn.com/'
        # 访问数据库取出信息
        try:
            homes = House.objects.filter(user=user)
            for home in homes:
                time = str(home.create_time)[:-13]
                houses.append({
                    'house_id': home.id,
                    'order_count': home.order_count,
                    'title': home.title,
                    'ctime': time,
                    'price': home.price,
                    'area_name': home.area.name,
                    'address': home.address,
                    'room_count': home.room_count,
                    'img_url': home.index_image_url,
                    'user_avatar': address + str(user.avatar)})

        except Exception as e:
            return JsonResponse({'errno': 4001,
                                 'errmsg': '查询数据库失败'})
        #拼接字典
        home_dict = {
            'houses': houses
        }

        return JsonResponse({'data': home_dict,
                             'errno': 0,
                             'errmsg': 'ok'})


class DistrictView(View):

    def get(self, request):
        '''获取地区列表'''
        district_list = cache.get('district_list')

        if not district_list:
            try:
                district_model_list = Area.objects.all()
            except Exception as e:
                return JsonResponse({'errno': 4001, 'errmsg': '获取城区数据失败'})

            district_list = []
            for district_model in district_model_list:
                district_list.append({'aid': district_model.id, 'aname': district_model.name})
            cache.set('district_list', district_list, 3600)

        return JsonResponse({'errno': 0, 'errmsg': '查询成功', 'data': district_list})


class HosesView(View):
    """
    首页房屋推荐
    请求方法: GET
    请求参数: 无
    """

    def get(self, request):
        """
        首页房屋推荐
        :param request: 请求对象
        :return: 响应对象
        """
        try:
            hosts = House.objects.filter(area__isnull=False)
        except BaseException as error:
            logger.error(error)
            return JsonResponse({'errno': 4004, 'errmsg': '数据错误'})
        # 构建响应数据
        data = []

        number = 0
        for host in hosts:
            data.append({'house_id': host.id,
                         'img_url': host.index_image_url,
                         'title': host.title})
            number += 1
            if number >= 5:
                break

        return JsonResponse({"errmsg": "OK", "errno": "0", "data": data})


class UploadPictureView(LoginRequiredMixin, View):

    def post(self, request, house_id):
        # 接收参数:
        house_image = request.FILES.get('house_image')
        house_image = house_image.read()
        key = storage(house_image)
        url = 'http://qcz5dw5aq.bkt.clouddn.com/'

        # 保存图片至制定房源
        try:
            house = House.objects.get(id=house_id)
            if house.index_image_url:
                HouseImage.objects.create(url=url + key, house=house_id)
            else:
                house.index_image_url = url + key
                house.save()

        except Exception as e:
            return JsonResponse({'errno': 4001, 'errmsg': '保存数据失败'})

        # 构造返回数据
        data = {
            "url": url + key
        }

        return JsonResponse({
            "errno": "0",
            "errmsg": "图片上传成功",
            "data": data
        })
